package me.chan.netty.framedecoder;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ThreadLocalRandom;

@Slf4j
public class LineBasedFrameClient {

    public static void main(String[] args) {

        String ls = System.getProperty("line.separator");
        Bootstrap bootstrap = new Bootstrap();
        NioEventLoopGroup eventLoopGroup = new NioEventLoopGroup();
        try {
            bootstrap.group(eventLoopGroup)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<NioSocketChannel>() {
                        @Override
                        protected void initChannel(NioSocketChannel ch) throws Exception {
                            ch.pipeline()
                                    .addLast(new LoggingHandler(LogLevel.DEBUG))
                                    .addLast(new ChannelInboundHandlerAdapter() {
                                        @Override
                                        public void channelActive(ChannelHandlerContext ctx) throws Exception {
                                            log.debug("prepare to send data...");
                                            ByteBuf buff = ctx.alloc().buffer();
                                            char c = '0';
                                            ThreadLocalRandom random = ThreadLocalRandom.current();
                                            for (int i = 0; i < 10; i++) {
                                                buff.writeBytes(genStr(c, (random.nextInt(128) + 1)).getBytes());
                                                buff.writeBytes(ls.getBytes());
                                                c += 1;
                                            }
                                            ctx.writeAndFlush(buff);
                                        }
                                    });
                        }
                    }).connect("127.0.0.1", 8080)
                        .sync()
                        .channel()
                        .closeFuture()
                        .sync();
        } catch (Exception ex) {
            log.error("cannot boot client", ex);
        } finally {
            eventLoopGroup.shutdownGracefully();
        }
    }


    private static String genStr(char ch, int times) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < times; i++) {
            sb.append(ch);
        }

        return sb.toString();
    }
}
